﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Fabrication
{
    public static class BuilderOptionExtensions
    {
        public static IBuilderOptions<T> ConstructUsing<T>(this IBuilderOptions<T> builderOptions, Func<T> creationMethod)
        {
            builderOptions.SetConstructionMethod(creationMethod);
            return builderOptions;
        }

        public static PropertySelector<T, TParam> For<T, TParam>(this IBuilderOptions<T> builderOptions, Expression<Func<T, TParam>> member)
        {
            return new PropertySelector<T, TParam>(builderOptions, member);
        }

        public static EnsurePropertySelector<T, TParam> Ensure<T, TParam>(this IBuilderOptions<T> builderOptions, Expression<Func<T, TParam>> member)
        {
            return new EnsurePropertySelector<T, TParam>(builderOptions, member);
        }

        public static LinkedPropertySelector<T, TParam> Link<T, TParam>(this IBuilderOptions<T> builderOptions, Expression<Func<T, TParam>> member)
        {
            return new LinkedPropertySelector<T, TParam>(builderOptions, member);
        }

        public static IChildBuilderOptions<TParent, TChild> ForChild<TParent, TChild>(this IBuilderOptions<TParent> builderOptions, Expression<Func<TParent, TChild>> member)
        {
            return new ChildBuilderOptions<TParent, TChild>(builderOptions, member);
        }

        public static T Generate<T>(this IBuilderOptions<T> builderOptions)
        {
            return Generate(builderOptions, 1).Single();
        }

        public static IEnumerable<T> Generate<T>(this IBuilderOptions<T> builderOptions, int minimumNumberOfItems, int maximumNumberOfItems)
        {
            if (minimumNumberOfItems < 1)
                throw new ArgumentException("Minimum number of items must be greater than 0", "minimumNumberOfItems");

            var numberOfItems = RandomNumberGenerator.GetInteger(minimumNumberOfItems, maximumNumberOfItems);

            return Generate(builderOptions, numberOfItems);
        }

        public static IEnumerable<T> Generate<T>(this IBuilderOptions<T> builderOptions, int numberOfItems)
        {
            if (numberOfItems < 1)
                throw new ArgumentException("Number of items must be greater than 0", "numberOfItems");

            var builder = new ItemBuilder<T>(builderOptions);

            var generatedItems = new List<T>();
            for (int i = 0; i < numberOfItems; i++)
                generatedItems.Add(builder.Build());

            return generatedItems;
        }
    }
}